import 'package:flutter/material.dart';

class CustomizeKeyboard extends StatefulWidget {
  const CustomizeKeyboard({super.key});

  @override
  State<CustomizeKeyboard> createState() => _CustomizeKeyboardState();
}

class _CustomizeKeyboardState extends State<CustomizeKeyboard> {
  final TextEditingController _controller = TextEditingController();
  bool _readOnly = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("自定义键盘")),
      resizeToAvoidBottomInset: false,
      body: SafeArea(
        child: Column(
          children: [
            const SizedBox(height: 50),
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(3),
                ),
              ),
              style: TextStyle(fontSize: 24),
              autofocus: true,
              showCursor: true,
              readOnly: _readOnly,
            ),
            IconButton(
              icon: Icon(Icons.keyboard),
              onPressed: () {
                setState(() {
                  _readOnly = !_readOnly;
                });
              },
            ),
            Spacer(),
            CustomKeyboard(
              onTextInput: (myText) {
                _insertText(myText);
              },
              onBackspace: () {
                _backspace();
              },
            ),
          ],
        ),
      ),
    );
  }

  void _insertText(String myText) {
    final text = _controller.text;
    final textSelection = _controller.selection;
    // print(textSelection);
    final newText = text.replaceRange(
      textSelection.start,
      textSelection.end,
      myText,
    );
    final myTextLength = myText.length;
    _controller.text = newText;
    _controller.selection = textSelection.copyWith(
      baseOffset: textSelection.start + myTextLength,
      extentOffset: textSelection.start + myTextLength,
    );
  }

  void _backspace() {
    final text = _controller.text;
    final textSelection = _controller.selection;
    final selectionLength = textSelection.end - textSelection.start;
    // There is a selection.
    if (selectionLength > 0) {
      final newText = text.replaceRange(
        textSelection.start,
        textSelection.end,
        '',
      );
      _controller.text = newText;
      _controller.selection = textSelection.copyWith(
        baseOffset: textSelection.start,
        extentOffset: textSelection.start,
      );
      return;
    }

    // The cursor is at the beginning.
    if (textSelection.start == 0) {
      return;
    }

    // Delete the previous character
    final previousCodeUnit = text.codeUnitAt(textSelection.start - 1);
    final offset = _isUtf16Surrogate(previousCodeUnit) ? 2 : 1;
    final newStart = textSelection.start - offset;
    final newEnd = textSelection.start;
    final newText = text.replaceRange(newStart, newEnd, '');
    _controller.text = newText;
    _controller.selection = textSelection.copyWith(
      baseOffset: newStart,
      extentOffset: newStart,
    );
  }

  bool _isUtf16Surrogate(int value) {
    return value & 0xF800 == 0xD800;
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

class CustomKeyboard extends StatelessWidget {
  const CustomKeyboard({
    super.key,
    this.onTextInput,
    this.onBackspace,
  });

  final ValueSetter<String>? onTextInput;
  final VoidCallback? onBackspace;

  void _textInputHandler(String text) => onTextInput?.call(text);

  void _backspaceHandler() => onBackspace?.call();

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 160,
      color: Colors.blue,
      child: Column(
        children: [
          buildRowOne(),
          buildRowTwo(),
          buildRowThree(),
          buildRowFour(),
          buildRowFive(),
        ],
      ),
    );
  }

  Expanded buildRowOne() {
    return Expanded(
      child: Row(
        children: [
          TextKey(text: '坚', onTextInput: _textInputHandler),
          TextKey(text: '果', onTextInput: _textInputHandler),
          TextKey(text: '祝', onTextInput: _textInputHandler),
        ],
      ),
    );
  }

  Expanded buildRowTwo() {
    return Expanded(
      child: Row(
        children: [
          TextKey(text: 'I', onTextInput: _textInputHandler),
          TextKey(text: 'n', onTextInput: _textInputHandler),
          TextKey(text: 'f', onTextInput: _textInputHandler),
          TextKey(text: 'o', onTextInput: _textInputHandler),
          TextKey(text: 'Q', onTextInput: _textInputHandler),
        ],
      ),
    );
  }

  Expanded buildRowThree() {
    return Expanded(
      child: Row(
        children: [
          TextKey(text: '十', onTextInput: _textInputHandler),
          TextKey(text: '五', onTextInput: _textInputHandler),
          TextKey(text: '周', onTextInput: _textInputHandler),
          TextKey(text: '年', onTextInput: _textInputHandler),
        ],
      ),
    );
  }

  Expanded buildRowFour() {
    return Expanded(
      child: Row(
        children: [
          TextKey(text: '生', onTextInput: _textInputHandler),
          TextKey(text: '日', onTextInput: _textInputHandler),
          TextKey(text: '快', onTextInput: _textInputHandler),
          TextKey(text: '乐', onTextInput: _textInputHandler),
          TextKey(text: '！', onTextInput: _textInputHandler),
        ],
      ),
    );
  }

  Expanded buildRowFive() {
    return Expanded(
      child: Row(
        children: [
          TextKey(text: ' 🎂', flex: 2, onTextInput: _textInputHandler),
          TextKey(text: ' 🎊', flex: 2, onTextInput: _textInputHandler),
          TextKey(text: '🎁', flex: 2, onTextInput: _textInputHandler),
          TextKey(text: '🎈', flex: 2, onTextInput: _textInputHandler),
          BackspaceKey(onBackspace: _backspaceHandler),
        ],
      ),
    );
  }
}

class TextKey extends StatelessWidget {
  const TextKey({super.key, required this.text, this.onTextInput, this.flex = 1});

  final String text;
  final ValueSetter<String>? onTextInput;
  final int flex;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: flex,
      child: Padding(
        padding: const EdgeInsets.all(1.0),
        child: Material(
          color: Colors.blue.shade300,
          child: InkWell(
            onTap: () {
              onTextInput!.call(text);
            },
            child: Center(child: Text(text)),
          ),
        ),
      ),
    );
  }
}

class BackspaceKey extends StatelessWidget {
  const BackspaceKey({super.key, this.onBackspace, this.flex = 1});

  final VoidCallback? onBackspace;
  final int flex;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: flex,
      child: Padding(
        padding: const EdgeInsets.all(1.0),
        child: Material(
          color: Colors.blue.shade300,
          child: InkWell(
            onTap: () {
              onBackspace?.call();
            },
            child: Center(child: Icon(Icons.backspace)),
          ),
        ),
      ),
    );
  }
}
